import json
from flask import Flask, request
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_restful import Api
from flask_restful import Resource
import datetime
import config
import base64
import urllib
import cv2
import numpy as np


app = Flask(__name__)
app.config.from_object(config)
db = SQLAlchemy(app)
api = Api(app)

'''数据库模型'''


'''
识别记录表
'''
class identificationRecord(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))
    state = db.Column(db.Integer)
    date_time = db.Column(db.DateTime, default=datetime.datetime.now)
    def return_json(self):
        return {
            'id':self.id,
            'name': self.name,
            'state':self.state,
            'date_time':self.date_time.strftime('%Y-%m-%d %H:%M:%S')
        }

'''
状态标记表
'''
class tateTag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    cv2state = db.Column(db.Integer)
    magstate= db.Column(db.Integer)
    date_time = db.Column(db.DateTime, default=datetime.datetime.now)
    def return_json(self):
        return {
            'id':self.id,
            'cv2state': self.cv2state,
            'magstate':self.magstate,
            'date_time':self.date_time.strftime('%Y-%m-%d %H:%M:%S')
        }
    def clear(self):
        self.cv2state  = 0
        self.magstate  = 0
        self.date_time = datetime.datetime.now()



'''
定时记录表
'''
class timerOfFeeding(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))
    hour = db.Column(db.Integer)
    minute = db.Column(db.Integer)
    weight = db.Column(db.Integer)
    date_time = db.Column(db.DateTime, default=datetime.datetime.now)
    def return_json(self):
        return {
            'id': self.id,
            'name':self.name,
            'hour':self.hour,
            'minute':self.minute,
            'weight':self.weight,
            'date_time':self.date_time.strftime('%Y-%m-%d %H:%M:%S')
        }

'''
喂食记录表
'''
class feedingRecords(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))
    manualfeeding = db.Column(db.Integer)
    automaticfeeding = db.Column(db.Integer)
    date_time = db.Column(db.DateTime, default=datetime.datetime.now)
    def return_json(self):
        return {
            'id': self.id,
            'name':self.name,
            'manualfeeding':self.manualfeeding,
            'automaticfeeding':self.automaticfeeding,
            'date_time':self.date_time.strftime('%Y-%m-%d %H:%M:%S')
        }


'''
余粮记录表
'''
class surplusGrainRecord(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(128))
    weight = db.Column(db.Integer)
    date_time = db.Column(db.DateTime, default=datetime.datetime.now)
    def return_json(self):
        return {
            'id':self.id,
            'name': self.name,
            'weight':(self.weight/10),
            'date_time':self.date_time.strftime('%Y-%m-%d %H:%M:%S')
        }



'''
添加定时
'''
class timerOfFeeding_add(Resource):
    def post(self):
        data = json.loads(request.get_data())
        duf = timerOfFeeding(name = data['name'],hour =data['hour'],minute =data['minute'],weight =data['weight'])
        db.session.add(duf)
        db.session.commit()
        return {"state":"true","data":"null"}

'''
获取定时列表
'''
class timerOfFeeding_get(Resource):
    def post(self):
        #data = json.loads(request.get_data())
        buf= {
            "state":"true",
            "data":[]
        }
        itembuf = timerOfFeeding.query.all()
        print(type(itembuf))
        for duff in itembuf:
            buf['data'].append(duff.return_json())
        return buf

'''
删除定时
'''
class timerOfFeeding_detele(Resource):
    def post(self):
        data = json.loads(request.get_data())
        b = timerOfFeeding.query.filter(timerOfFeeding.id == data['id']).first()
        db.session.delete(b)
        db.session.commit()
        return {"state":"true","data":"null"}


class getImage(Resource):
    def get(self):
        image_url = "http://192.168.0.150:8080/stream.mjpg"
        classfier= cv2.CascadeClassifier("C:\\Users\\glyn\\AppData\\Local\\Programs\\Python\\Python38\\Lib\\site-packages\\cv2\data\\haarcascade_frontalcatface.xml")
        imgResp=urllib.request.urlopen(image_url)
        imgNp=np.array(bytearray(imgResp.read()),dtype=np.uint8)
        img=cv2.imdecode(imgNp,-1)
        print(type(img))
        grey = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        faceRects = classfier.detectMultiScale(grey, scaleFactor = 1.2, minNeighbors = 3, minSize = (32, 32))
        if len(faceRects) > 0:            #大于0则检测到猫脸
            for faceRect in faceRects:  #单独框出每一张猫脸
                x, y, w, h = faceRect
                cv2.rectangle(img, (x - 10, y - 10), (x + w + 10, y + h + 10), (0, 255, 0), 2)
            duf = identificationRecord( name= 'cat' , state = len(faceRects))
            db.session.add(duf)

            buff = tateTag.query.first()
            buff.cv2state = 1
            buff.date_time = datetime.datetime.now()

            db.session.commit()
        image = cv2.imencode('.jpg',img)[1]
        ss = base64.b64encode(image)
        return  {
            "state":"true",
            "data":"data:image/jpg;base64,"+ss.decode('ascii')
            }

        # files = requests.get(image_url)
        # s = base64.b64encode(files.content)
        # return +("<h5>"+"data:image/jpg;base64,"+s.decode('ascii')+"</h5>")


'''
记录余粮
'''
class surplusGrainRecord_add(Resource):
    def post(self):
        data = json.loads(request.get_data())
        duf = surplusGrainRecord(name = data['name'],weight =(data['weight']*100))
        db.session.add(duf)
        db.session.commit()
        return {"state":"true","data":"null"}


'''
获取所有余粮记录
'''
class surplusGrainRecord_get(Resource):
    def post(self):
        #data = json.loads(request.get_data())
        buf= {
            "state":"true",
            "data":[]
        }
        itembuf = surplusGrainRecord.query.all()
        print(type(itembuf))
        for duff in itembuf:
            buf['data'].append(duff.return_json())
        return buf
'''
获取最后一条余粮记录
'''
class surplusGrainRecord_get_a(Resource):
    def post(self):
        #data = json.loads(request.get_data())
        buf= {
            "state":"true",
            "data":[]
        }
        itembuf = surplusGrainRecord.query.order_by(-surplusGrainRecord.date_time).first()
        print(type(itembuf))
        buf['data'].append(itembuf.return_json())
        return buf


'''
记录喂食
'''
class feedingRecords_add(Resource):
    def post(self):
        data = json.loads(request.get_data())
        duf = feedingRecords(name = data['name'],manualfeeding =(data['manualfeeding']*100),automaticfeeding =(data['automaticfeeding']*100))
        db.session.add(duf)
        db.session.commit()
        return {"state":"true","data":"null"}


'''
获取所有喂食记录
'''
class feedingRecords_get(Resource):
    def post(self):
        #data = json.loads(request.get_data())
        buf= {
            "state":"true",
            "data":[]
        }
        itembuf = feedingRecords.query.all()
        print(type(itembuf))
        for duff in itembuf:
            buf['data'].append(duff.return_json())
        return buf




'''
获取所有是识别记录
'''
class identificationRecord_get(Resource):
    def post(self):
        #data = json.loads(request.get_data())
        buf= {
            "state":"true",
            "data":[]
        }
        itembuf = identificationRecord.query.all()
        print(type(itembuf))
        for duff in itembuf:
            buf['data'].append(duff.return_json())
        return buf



'''
获取最近一条识别记录
'''
class identificationRecord_get_a(Resource):
    def post(self):
        #data = json.loads(request.get_data())
        buf= {
            "state":"true",
            "data":[]
        }
        itembuf = identificationRecord.query.order_by(-identificationRecord.date_time).first()
        print(type(itembuf))
        buf['data'].append(itembuf.return_json())
        return buf

'''
初始化状态表
'''
class tateTag_add(Resource):
    def post(self):
        data = json.loads(request.get_data())
        duf = tateTag(cv2state = data['cv2state'],magstate = data['magstate'])
        db.session.add(duf)
        db.session.commit()
        return {"state":"true","data":"null"}

'''
得到状态
'''

class tateTag_get(Resource):
    def post(self):
        buf= {
            "state":"true",
            "data":[]
        }
        duf = tateTag.query.first()
        buf['data'].append(duf.return_json())
        duf.clear()
        db.session.commit()
        return buf


'''
设置状态
'''
class tateTag_set(Resource):
    def post(self):
        data = json.loads(request.get_data())
        buf= {
            "state":"true",
            "data":[]
        }
        duf = tateTag.query.first()
        buf['data'].append(duf.return_json())
        duf.cv2state = data['cv2state']
        duf.magstate = data['magstate']
        duf.date_time = datetime.datetime.now()
        db.session.commit()
        return buf


#定时操作
api.add_resource(timerOfFeeding_add, '/timerOfFeeding_add')                                      #已测试
api.add_resource(timerOfFeeding_get, '/timerOfFeeding_get')                                      #已测试
api.add_resource(timerOfFeeding_detele, '/timerOfFeeding_detele')                                #已测试


#余粮操作
api.add_resource(surplusGrainRecord_add, '/surplusGrainRecord_add')                              #已测试
api.add_resource(surplusGrainRecord_get, '/surplusGrainRecord_get')                              #已测试
api.add_resource(surplusGrainRecord_get_a, '/surplusGrainRecord_get_a')                          #已测试


#喂食操作
api.add_resource(feedingRecords_add, '/feedingRecords_add')                                      #已测试
api.add_resource(feedingRecords_get, '/feedingRecords_get')                                      #已测试


#摄像头识别操作
api.add_resource(getImage, '/')                                                                  #已测试
api.add_resource(identificationRecord_get, '/identificationRecord_get')                          #已测试
api.add_resource(identificationRecord_get_a, '/identificationRecord_get_a')                      #已测试

#状态处理
api.add_resource(tateTag_add, '/tateTag_add')                                                    #已测试
api.add_resource(tateTag_get, '/tateTag_get')                                                    #已测试
api.add_resource(tateTag_set, '/tateTag_set')                                                    #已测试


migrate = Migrate(app, db)
